package org.batatasframework.support.loader;

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.batatasframework.properties.PropertiesDefine;
import org.batatasframework.properties.PropertiesResource;
import org.batatasframework.support.database.TableInfo;
import org.batatasframework.support.database.jdbc.ConnectionAccessor;
import org.batatasframework.support.database.jdbc.DatabaseAccessor;
import org.batatasframework.support.database.metadatas.DatabaseMetadataResource;
import org.batatasframework.support.database.metadatas.TableMetadata;
import org.batatasframework.support.definition.TableDefinition;
import org.batatasframework.support.definition.TableDefinitionParser;
import org.batatasframework.support.factory.TableDefinitionRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;


/**
 * <pre>
 * 这里定义的是如何解析定义文件，包括，查询定义和指标定义两种文件；
 * 
 * 解析后会生成一个{@link TableDefinition}，这里的上下文是根据定义生成的，可以直接引用
 * 也可以是以这个为模板，来生成一个子上下文，可以在子上下文里加上一些特定的信息
 * </pre>
 * @author jackson
 *
 */
public abstract class DatabasePropertiesLoader extends CommonPropertiesLoader{

	/**
	 * 这里可能需要管理多数据源的情况
	 */
	@Autowired
	@Qualifier("${db.attr.source}")
	protected DataSource dataSource;
	
	/** 这里应该是几个地方可以共用的 */
	protected final DatabaseMetadataResource databaseMetadataSources;
	
	protected DatabasePropertiesLoader(){
		databaseMetadataSources = createDatabaseMetadataSources();
	}
	
	protected DatabaseMetadataResource createDatabaseMetadataSources() {
		return DatabaseMetadataResource.getResource();
	}
	
	public DatabaseMetadataResource getDatabaseMetadataSources() {
		return databaseMetadataSources;
	}

	public TableMetadata loadTableMetadata(ConnectionAccessor connectionAccessor, TableInfo tableInfo) throws Exception{
		return databaseMetadataSources.loadTableMetadata(connectionAccessor, tableInfo);
	}

	/** 这里使用了连接，在这个方法被调用的地方，需要安全关闭 */
	public DatabaseAccessor buildDatabaseAccessor() throws Exception {
		return new DatabaseAccessor(databaseMetadataSources, dataSource.getConnection());
	}
	
	protected abstract TableDefinitionRegistry getTableFactoryRegistry();
	
	@SuppressWarnings("unchecked")
	@Override
	protected void parseLines(PropertiesResource properties) throws Exception {
		
		//解析到具体的上下文件里
	
		Class<? extends TableDefinitionParser> dtdpClass = DefaultTableDefinitionParser.class;
		Class<? extends TableDefinitionParser> ttdpClass;
		Map<Class<?>, TableDefinitionParser> parserMap = new HashMap<>();
		parserMap.put(dtdpClass, new DefaultTableDefinitionParser());
		
		try(DatabaseAccessor databaseAccessor = buildDatabaseAccessor()){
			
			//解析分组里的项定义
			for(PropertiesDefine b : properties.resources("define")){
				DatabasePropertiesParser dg = new DatabasePropertiesParser(
						databaseAccessor, 
						databaseMetadataSources, 
						getTableFactoryRegistry(), b);
				dg.init();
				
				ttdpClass = (Class<? extends TableDefinitionParser>)dg.getClassType("parser.class", dtdpClass);
				TableDefinitionParser parser = parserMap.get(ttdpClass);
				if(null == parser){
					parser = ttdpClass.newInstance();
					parserMap.put(ttdpClass, parser);
				}
				
				TableDefinition tableDefinition = parser.parse(dg);
				
				if(null != tableDefinition){
					String name = dg.getString("name", dg.getTableName());
					getTableFactoryRegistry().registerTableDefinition(name, tableDefinition);
				}
			}
		}
		
	}
}
